package com.witmore.neutron.ai.mcp.server.trading.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jk.mp.wx.client.WeChatServiceClient;
import com.jk.mp.wx.config.WechatServiceProperties;
import com.jk.mp.wx.request.SendMsgTemplateRequest;
import com.jk.mp.wx.response.SendMsgTemplateResponse;
import com.witmore.neutron.ai.mcp.server.trading.db.entity.ScorpionTradingUserDO;
import com.witmore.neutron.ai.mcp.server.trading.db.entity.ScorpionWechatMessageRecordDO;
import com.witmore.neutron.ai.mcp.server.trading.db.mapper.ScorpionTradingUserMapper;
import com.witmore.neutron.ai.mcp.server.trading.db.mapper.ScorpionWechatMessageRecordMapper;
import com.witmore.neutron.ai.mcp.server.trading.dto.StockAlertNotificationDTO;
import com.witmore.neutron.ai.mcp.server.trading.service.WechatNotificationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import static com.jk.mp.wx.constant.WeChatUtils.ACCESS_TOKEN_URL;

/**
 * 微信通知服务实现类
 * Author: 豆子高
 * Date: 2025/12/19
 */
@Slf4j
@Service
public class WechatNotificationServiceImpl implements WechatNotificationService {

    @Autowired
    private ScorpionTradingUserMapper scorpionTradingUserMapper;

    @Autowired
    private ScorpionWechatMessageRecordMapper wechatMessageRecordMapper;

    @Autowired
    private WechatServiceProperties wechatServiceProperties;

    private final RestTemplate restTemplate = new RestTemplate();

    // 您提供的模板ID
    private static final String STOCK_ALERT_TEMPLATE_ID = "zwhqD8WidSoa_wWM3271IZT4nl89Arc9zYH1pebhcY4";

    @Autowired
    private WeChatServiceClient wechatServiceClient;

    /**
     * 获取微信AccessToken
     */
    private String getAccessToken() {
        try {
            String url = String.format(ACCESS_TOKEN_URL, wechatServiceProperties.getAppId(), wechatServiceProperties.getAppSecret());
            ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);

            if (response.getStatusCode().is2xxSuccessful() && StringUtils.hasText(response.getBody())) {
                Map<String, Object> result = JSON.parseObject(response.getBody(), Map.class);
                String accessToken = (String) result.get("access_token");

                if (StringUtils.hasText(accessToken)) {
                    return accessToken;
                } else {
                    log.error("获取AccessToken失败：{}", response.getBody());
                }
            }
        } catch (Exception e) {
            log.error("获取微信AccessToken异常", e);
        }

        return null;
    }

    @Override
    public boolean sendStockAlertTemplateMessage(Long userId, StockAlertNotificationDTO notification) {
        try {
            // 通过用户ID查找用户信息
            ScorpionTradingUserDO user = scorpionTradingUserMapper.selectById(userId);
            if (user == null || !StringUtils.hasText(user.getOpenid())) {
                log.warn("用户不存在或未绑定微信，用户ID：{}", userId);
                return false;
            }

            return sendWechatTemplateMessage(user.getOpenid(), notification);

        } catch (Exception e) {
            log.error("发送股票异动预警模板消息失败，用户ID：{}，股票：{}", userId, notification.getStockCode(), e);
            return false;
        }
    }

    /**
     * 发送微信模板消息
     */
    private boolean sendWechatTemplateMessage(String openId, StockAlertNotificationDTO notification) {
        try {
            // 获取AccessToken
            String accessToken = getAccessToken();
            if (!StringUtils.hasText(accessToken)) {
                log.error("获取微信AccessToken失败");
                return false;
            }

            // 构建模板消息数据
            Map<String, Object> templateData = buildTemplateMessageData(notification);

            // 构建请求体
            SendMsgTemplateRequest request = new SendMsgTemplateRequest();
            request.setTouser(openId);
            request.setTemplate_id(STOCK_ALERT_TEMPLATE_ID);
            request.setUrl("https://ai.unimodel.com/h5x/neutron/stock/abnormal/detail.html?id=" + notification.getAbnormalRecordId());
            request.setData(templateData);
            // 添加防重入ID
            request.setClient_msg_id("stock_alert_" + System.currentTimeMillis() + "_" + notification.getStockCode());

            // 发送请求
            SendMsgTemplateResponse response = wechatServiceClient.sendTemplateMessage(request, accessToken);
            boolean success = response != null && response.isSuccess();
            String errmsg = success ? "请求成功" : (response != null ? response.getErrMsg() : "响应为空");
            // 保存消息记录
            String messageContent = buildTemplateMessageContent(notification);
            saveTemplateMessageRecord(openId, notification, JSONObject.toJSONString(request), success, errmsg, Objects.requireNonNull(response).getMsgid());
            log.info("股票异动预警模板消息发送{}，OpenID：{}，股票：{}，消息ID：{},请求结果:{}",
                    success, openId, notification.getStockCode(), Objects.requireNonNull(response).getMsgid(), errmsg);
            return success;
        } catch (Exception e) {
            log.error("发送微信模板消息异常，OpenID：{}", openId, e);
            return false;
        }
    }

    /**
     * 构建模板消息数据
     */
    private Map<String, Object> buildTemplateMessageData(StockAlertNotificationDTO notification) {
        Map<String, Object> templateData = new HashMap<>();

        // 根据新的模板结构构建数据
        // 预警编码：{{character_string14.DATA}} - 显示股票代码
        templateData.put("character_string14", createTemplateDataItem(notification.getStockCode()));

        // 预警名称：{{phrase8.DATA}} - 显示股票名称
        // 使用正则表达式匹配要移除的字符：-、*、换行符
        String stockName = notification.getStockName().replaceAll("[-*a-zA-Z]", "");
        templateData.put("phrase8", createTemplateDataItem(stockName));

        // 预警等级：{{thing4.DATA}} - 显示上涨或下跌的幅度
        String changeText = notification.getChangeRatio().compareTo(java.math.BigDecimal.ZERO) >= 0
                ? String.format("上涨+%.2f%%", notification.getChangeRatio())
                : String.format("下跌%.2f%%", notification.getChangeRatio().abs());
        templateData.put("thing4", createTemplateDataItem(changeText));

        // 预警时间：{{thing6.DATA}} - 显示预警的时间
        templateData.put("thing6", createTemplateDataItem(
                notification.getAlertTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))));

        return templateData;
    }

    /**
     * 创建模板数据项
     */
    private Map<String, String> createTemplateDataItem(String value) {
        Map<String, String> item = new HashMap<>();
        item.put("value", value);
        return item;
    }

    /**
     * 构建模板消息内容（用于记录）
     */
    private String buildTemplateMessageContent(StockAlertNotificationDTO notification) {
        String alertType = notification.getAbnormalType().contains("上涨") ? "📈" : "📉";
        String changeText = notification.getChangeRatio().compareTo(java.math.BigDecimal.ZERO) >= 0
                ? String.format("上涨+%.2f%%", notification.getChangeRatio())
                : String.format("下跌%.2f%%", notification.getChangeRatio().abs());

        return String.format(
                """
                        %s 股票异动预警模板消息
                        
                        预警编码：%s
                        预警名称：%s
                        预警等级：%s
                        预警时间：%s
                        
                        💡 请注意风险，理性投资！""",
                alertType,
                notification.getStockCode(),
                notification.getStockName(),
                changeText,
                notification.getAlertTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
        );
    }

    /**
     * 保存模板消息记录
     */
    private void saveTemplateMessageRecord(String openId, StockAlertNotificationDTO notification,
                                           String messageContent, boolean success, String errorMsg, Long msgId) {
        try {
            ScorpionTradingUserDO scorpionTradingUserDO = scorpionTradingUserMapper.selectOne(new LambdaQueryWrapper<ScorpionTradingUserDO>()
                    .eq(ScorpionTradingUserDO::getOpenid, openId)
            );
            ScorpionWechatMessageRecordDO record = new ScorpionWechatMessageRecordDO();
            record.setUserOpenid(openId);
            record.setMessageContent(messageContent);
            record.setStatus(success ? (byte) 1 : (byte) 2); // 1-已推送 2-推送失败
            record.setRemark(success ?
                    String.format("股票异动预警模板消息推送成功，股票：%s，消息ID：%s", notification.getStockCode(), msgId)
                    : String.format("模板消息推送失败：%s", (errorMsg != null ? errorMsg : "未知错误")));
            record.setCreateTime(LocalDateTime.now());
            record.setUpdateTime(LocalDateTime.now());
            record.setUserId(scorpionTradingUserDO.getId());
            record.setUserName(scorpionTradingUserDO.getUserName());
            record.setIsDeleted((byte) 0);

            wechatMessageRecordMapper.insert(record);

        } catch (Exception e) {
            log.error("保存微信模板消息记录失败", e);
        }
    }

}
